package com.ruoyi.resume.service.impl;

import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.resume.domain.model.Category;
import com.ruoyi.resume.domain.model.ResumeTag;
import com.ruoyi.resume.domain.model.SplitResumeResult;
import com.ruoyi.resume.domain.request.LabelingRequest;
import com.ruoyi.resume.domain.response.ResumeAndTagsResp;
import com.ruoyi.resume.mapper.CategoryMapper;
import com.ruoyi.resume.mapper.ResumeTagMapper;
import com.ruoyi.resume.service.ResumeService;
import com.ruoyi.resume.service.TaskProcessor;
import com.ruoyi.resume.utils.RecursiveCategoryFinder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Component
public class UpdateCategoriesProcessor implements TaskProcessor {
    private static final Logger logger = LoggerFactory.getLogger(UpdateCategoriesProcessor.class);
    private final ResumeService resumeService;
    private final CategoryMapper categoryMapper;
    private final ResumeTagMapper resumeTagMapper;
    private final RestTemplate restTemplate = new RestTemplate(); // RestTemplate 实例

    public UpdateCategoriesProcessor(ResumeService resumeService, CategoryMapper categoryMapper, ResumeTagMapper resumeTagMapper) {
        this.resumeService = resumeService;
        this.categoryMapper = categoryMapper;
        this.resumeTagMapper = resumeTagMapper;
    }

    @Override
    public void process(Integer tagId) {
        try {
            // 第一步：查找有效分类 ID
            Integer validCategoryId = getValidCategoryId(tagId);

            // 第二步：获取分类和算法地址
            Category category = getCategoryById(validCategoryId);
            String algorithmAddress = getAlgorithmAddress(validCategoryId);

            // 第三步：分页处理简历数据
            List<Map<String, Integer>> allProcessedLabels = processResumesInBatches(category, algorithmAddress);

            // 打印所有处理过的标签
            logger.info("所有处理的标签：{}", allProcessedLabels);
        } catch (Exception e) {
            logger.error("更新任务失败，Tag ID：" + tagId + "，错误：" + e.getMessage(), e);
        }
    }

    // 查找有效分类 ID
    private Integer getValidCategoryId(Integer tagId) {
        Integer categoryId = categoryMapper.findCategoryIdByTagId(tagId);
        if (categoryId == null) {
            throw new RuntimeException("未找到 tagId 对应的 category_id，Tag ID：" + tagId);
        }

        RecursiveCategoryFinder finder = new RecursiveCategoryFinder(categoryMapper);
        return finder.findValidAlgorithmCategoryId(categoryId);
    }

    // 获取分类
    private Category getCategoryById(Integer validCategoryId) {
        Category category = categoryMapper.selectCategoryById(validCategoryId);
        if (category == null) {
            throw new RuntimeException("未找到分类信息，Category ID：" + validCategoryId);
        }
        return category;
    }

    // 获取算法地址
    private String getAlgorithmAddress(Integer validCategoryId) {
        String algorithmAddress = categoryMapper.findAlgorithmByCategoryId(validCategoryId);
        if (algorithmAddress == null || algorithmAddress.isEmpty()) {
            throw new RuntimeException("未找到算法地址，Category ID：" + validCategoryId);
        }
        logger.info("找到有效算法地址，Category ID：{}，算法地址：{}", validCategoryId, algorithmAddress);
        return algorithmAddress;
    }

    // 分页处理简历数据
    private List<Map<String, Integer>> processResumesInBatches(Category category, String algorithmAddress) {
        List<Map<String, Integer>> allProcessedLabels = new ArrayList<>();
        TableDataInfo tableDataInfo;

//        do {
        // 调用服务方法，分页获取简历数据
        tableDataInfo = resumeService.getResumesByRange(
                null, // 姓名（String类型）
                null, // 性别（String类型）
                null, // 籍贯（String类型）
                null, // 政治面貌（String类型）
                null, // 当前页码（Integer类型）
                null // 每页数量（Integer类型）
        );

        logger.info("获取到的简历列表：{}", tableDataInfo.getRows());

        // 遍历当前页简历数据
        for (Object row : tableDataInfo.getRows()) {
            ResumeAndTagsResp resume = (ResumeAndTagsResp) row; // 需要确保类型转换正确
            Integer resumeId = resume.getBaseInfo().getId();
            processSingleResume(resumeId, category, algorithmAddress, allProcessedLabels);
        }
//        } while (tableDataInfo.getRows() != null && !tableDataInfo.getRows().isEmpty());

        return allProcessedLabels;
    }
    // 处理单个简历
    private void processSingleResume(Integer resumeId, Category category, String algorithmAddress, List<Map<String, Integer>> allProcessedLabels) {
        try {
            SplitResumeResult splitResult = resumeService.getResumeContentById(resumeId);
            logger.info("简历 ID：{}，解析结果：{}", resumeId, splitResult);

            LabelingRequest request = new LabelingRequest();
            request.setSplitResumeResult(splitResult);
            request.setCategory(category);

            ResponseEntity<List> response = restTemplate.postForEntity(algorithmAddress, request, List.class);
            if (response.getStatusCode().is2xxSuccessful() && response.getBody() != null) {
                List<Map<String, Integer>> labels = response.getBody();
                logger.info("算法返回的标签：{}", labels);

                // 插入标签到数据库
                insertLabelsToDatabase(resumeId, labels);

                allProcessedLabels.addAll(labels);
            } else {
                logger.warn("调用算法接口返回非 2xx 响应: {}", response.getStatusCode());
            }
        } catch (Exception e) {
            logger.error("处理简历失败，简历 ID：{}，错误：{}", resumeId, e.getMessage());
        }


    }

    private void insertLabelsToDatabase(Integer resumeId, List<Map<String, Integer>> labels) {
        if (labels.isEmpty()) {
            logger.warn("insertLabelsToDatabase: labels 为空，跳过插入操作");
            return;
        }

        for (Map<String, Integer> label : labels) {
            for (Map.Entry<String, Integer> entry : label.entrySet()) {
                String tagValue = entry.getKey();
                Integer tagId = entry.getValue();

                ResumeTag resumeTag = new ResumeTag();
                resumeTag.setResumeId(resumeId);
                resumeTag.setTagId(tagId);
                resumeTag.setTagValue(tagValue);

                try {
                    // 检查是否已存在
                    int count = resumeTagMapper.countResumeTag(resumeId, tagId);
                    if (count == 0) {
                        resumeTagMapper.insertResumeTag(resumeTag);
                        logger.info("插入标签：resumeId={}, tagId={}, tagValue={}", resumeId, tagId, tagValue);
                    } else {
                        logger.warn("标签已存在：resumeId={}, tagId={}", resumeId, tagId);
                    }
                } catch (Exception e) {
                    logger.error("插入标签到数据库失败：resumeId={}, tagId={}, tagValue={}", resumeId, tagId, tagValue, e);
                }
            }
        }
    }

}
